package com.pomelo.base.core.util;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Map;

import org.apache.http.client.HttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.pomelo.base.core.bean.ResultBean;

/**
 * http请求工具
 *
 * @author biankudingcha
 * @date: 2021-07-31
 * @since 0.5.0
 */
@Component
public class RestTemplateUtils {

    /**
     * RestTemplate对象
     */
    private static RestTemplate restTemplate;

    /**
     * http请求连接
     */
    private static HttpClient httpClient;

    /**
     * 获取RestTemplate对象
     *
     * @return RestTemplate
     */
    public static RestTemplate getRestTemplate() {
        return restTemplate;
    }

    /**
     * 设置RestTemplate
     *
     * @param restTemplate RestTemplate
     */
    @Autowired
    public void setRestTemplate(RestTemplate restTemplate) {
        RestTemplateUtils.restTemplate = restTemplate;
    }

    /**
     * 设置http请求连接
     *
     * @param httpClient 请求连接
     */
    @Autowired
    public void setHttpClient(HttpClient httpClient) {
        RestTemplateUtils.httpClient = httpClient;
    }

    /**
     * 发送get请求
     *
     * @param url 请求url
     * @return ResultBean
     * @throws Exception
     */
    public static ResponseEntity<ResultBean> getHttp(String url) throws Exception {
        return getHttp(url, ResultBean.class);
    }

    /**
     * 发送get请求
     *
     * @param <T> T
     * @param url  请求url
     * @param responseType 返回的类型
     * @return T
     * @throws Exception
     */
    public static <T> ResponseEntity<T> getHttp(String url, Class<T> responseType) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        ResponseEntity<T> response = restTemplate.getForEntity(url, responseType);
        return response;
    }

    /**
     * 发送post请求，参数键值对
     *
     * @param url 请求url
     * @param param 请求参数
     * @return ResultBean
     * @throws Exception
     */
    public static ResponseEntity<ResultBean> postHttp(String url, MultiValueMap<String, Object> param)
        throws Exception {
        return postHttp(url, param, ResultBean.class);
    }

    /**
     * 发送post请求，参数键值对
     *
     * @param <T> T
     * @param url 请求url
     * @param param 参数
     * @param responseType 返回类型
     * @return T
     * @throws Exception
     */
    public static <T> ResponseEntity<T> postHttp(String url, MultiValueMap<String, Object> param, Class<T> responseType)
        throws Exception {
        return postHttp(url, param, responseType, null);
    }

    /**
     * 发送post请求，参数键值对
     *
     * @param <T> T
     * @param url 请求url
     * @param param 参数
     * @param responseType 返回类型
     * @param headers 头信息
     * @return T
     * @throws Exception
     */
    public static <T> ResponseEntity<T> postHttp(String url, MultiValueMap<String, Object> param, Class<T> responseType,
        HttpHeaders headers) throws Exception {
        if (headers == null) {
            headers = new HttpHeaders();
        }
        if (headers.getContentType() == null) {
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        }
        HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(param, headers);
        ResponseEntity<T> response = restTemplate.postForEntity(url, request, responseType);
        return response;
    }

    /**
     * 发送post请求，json格式
     *
     * @param url 请求url
     * @param param 参数
     * @return ResultBean
     * @throws Exception
     */
    public static ResponseEntity<ResultBean> postHttp(String url, Map<String, Object> param) throws Exception {
        return postHttp(url, param, ResultBean.class, null);
    }

    /**
     * 发送post请求，json格式
     *
     * @param <T> T
     * @param url 请求url
     * @param param 参数
     * @param responseType 返回类型
     * @return T
     * @throws Exception
     */
    public static <T> ResponseEntity<T> postHttp(String url, Map<String, Object> param, Class<T> responseType)
        throws Exception {
        return postHttp(url, param, responseType, null);
    }

    /**
     * 发送post请求，json格式
     *
     * @param <T> T
     * @param url 请求url
     * @param param 参数
     * @param responseType 返回类型
     * @param headers 头信息
     * @return T
     * @throws Exception
     */
    public static <T> ResponseEntity<T> postHttp(String url, Map<String, Object> param, Class<T> responseType,
        HttpHeaders headers) throws Exception {
        if (headers == null) {
            headers = new HttpHeaders();
        }
        if (headers.getContentType() == null) {
            headers.setContentType(MediaType.APPLICATION_PROBLEM_JSON);
        }
        HttpEntity<Map<String, Object>> request = new HttpEntity<>(param, headers);
        ResponseEntity<T> response = restTemplate.postForEntity(url, request, responseType);
        return response;
    }

    /**
     * 发送post请求获取文件
     *
     * @param url 请求url
     * @param requestParam 参数
     * @param headers 头信息
     * @return InputStream
     * @throws Exception
     */
    public static InputStream postHttpInputStream(String url, MultiValueMap<String, Object> requestParam,
        HttpHeaders headers) throws Exception {
        HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(requestParam, headers);
        ResponseEntity<byte[]> responseEntity = RestTemplateUtils.getRestTemplate().exchange(url, HttpMethod.POST,
            entity, byte[].class);
        byte[] body = responseEntity.getBody();
        InputStream input = new ByteArrayInputStream(body);
        return input;
    }

    /**
     * 发送get请求获取文件
     *
     * @param url 请求url
     * @param headers 头信息
     * @return InputStream
     * @throws Exception
     */
    public static InputStream getHttpInputStream(String url, HttpHeaders headers) throws Exception {
        HttpEntity<String> entity = new HttpEntity<>(headers);
        ResponseEntity<byte[]> responseEntity = RestTemplateUtils.getRestTemplate().exchange(url, HttpMethod.GET,
            entity, byte[].class);
        byte[] body = responseEntity.getBody();
        InputStream input = new ByteArrayInputStream(body);
        return input;
    }

    /**
     * 获取RestTemplate
     *
     * @param connectionRequestTimeout 请求连接超时
     * @param connectTimeout 连接超时时间
     * @param readTimeout 读取超时时间
     * @return RestTemplate
     * @throws Exception
     */
    public static RestTemplate getRestTemplate(int connectionRequestTimeout, int connectTimeout, int readTimeout)
        throws Exception {
        HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(
            httpClient);
        httpRequestFactory.setConnectionRequestTimeout(connectionRequestTimeout);
        httpRequestFactory.setConnectTimeout(connectTimeout);
        httpRequestFactory.setReadTimeout(readTimeout);
        return new RestTemplate(httpRequestFactory);
    }

}